<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
<script>
class Player {
  constructor(name, teamColor) {
    this.name = name;
    this.teamColor = teamColor;
    this.state = 'alive'
    this.win = this.win.bind(this, arguments)
    this.lose = this.lose.bind(this, arguments)
    this.die = this.die.bind(this, arguments)
    this.remove = this.remove.bind(this, arguments)
    this.changeTeam = this.changeTeam.bind(this, arguments)
  }
  win() {
    console.log(this.name + ' win');
  }
  lose() {
    console.log(this.name + 'lose');
  }
  die() {
    this.state = 'die';
    // 给中介者发送消息，玩家死亡
    playerDirector.receiveMessage('playerDead', this);
  }
  remove() {
    // 给中介者发送消息，移除一个玩家
    playerDirector.receiveMessage('removePlayer', this);
  }
  changeTeam(color) {
    // 给中介者发送消息，玩家换队
    playerDirector.receiveMessage('changeTeam', this, color);
  }
}
let playerFactory = (name, teamColor) => {
  let newPlayer = new Player(name, teamColor);
  playerDirector.receiveMessage('addPlayer', newPlayer);
  return newPlayer;
}

class Operation {
  constructor() {
    this.players = {}
    this.addPlayer = this.addPlayer.bind(this)
    this.removePlayer = this.removePlayer.bind(this)
    this.changeTeam = this.changeTeam.bind(this)
    this.playerDead = this.playerDead.bind(this)
  }
  addPlayer(player) {
    let teamColor = player.teamColor;
    // 如果该颜色的玩家还没有成立队伍，则新成立一个队伍
    this.players[teamColor] = this.players[teamColor] || [];
    this.players[teamColor].push(player);
  }
  removePlayer(player) {
    let teamColor = player.teamColor;
    let teamPlyers = this.players[teamColor] || [];
    for(let i = teamPlyers.length-1; i >= 0; i--) {
      if(teamPlyers[i] === player) {
        teamPlyers.splice(i, 1)
      }
    }
  }
  changeTeam(player, newTeamColor) {
    this.removePlayer(player);
    player.teamColor = newTeamColor;
    this.addPlayer(player);
  }
  playerDead(player) {
    let teamColor = player.teamColor;
    // 玩家所在队伍
    let teamPlayers = this.players[teamColor];
    let all_dead = true;
    for(let player of teamPlayers) {
      if(player.state !== 'dead') {
        all_dead = false;
        break;
      }
    }
    if(all_dead = true) {
      // 全部死亡
      for(let player of teamPlayers) {
        // 本队所有玩家 lose
        player.lose()
      }
      for(let color in this.players) {
        if(color !== teamColor) {
          // 其他队伍的玩家
          let teamPlayers = this.players[color];
          for(let player of teamPlayers) {
            // 其他队伍所有玩家 win 
            player.win()
          }
        }
      }
    }
  }
}
class PlayerDirector {
  constructor() {
    this.operations = new Operation()
  }
  receiveMessage() {
    // arguments 的第一个参数为消息名称
    let message = Array.prototype.shift.call(arguments);
    this.operations[message].apply(this, arguments)
  }
}
let playerDirector = new PlayerDirector()

let player1 = playerFactory('皮蛋', 'red')
let player2 = playerFactory('瘦肉', 'red')
let player3 = playerFactory('荔湾', 'red')
let player4 = playerFactory('艇仔', 'red')

let player5 = playerFactory('皮蛋1', 'blue')
let player6 = playerFactory('瘦肉1', 'blue')
let player7 = playerFactory('荔湾1', 'blue')
let player8 = playerFactory('艇仔1', 'blue')

player1.remove()
player2.remove()
player3.changeTeam('blue')
player4.die()

</script>
</body>
</html>